import numpy as np
import numpy.matlib

'''
其他论文参考： https://www.fx361.com/page/2021/0420/14011331.shtml
'''

def centroid_alg(numbers, scores, dimension):
    '''
        使用重心法对数据清晰化，返回归一化后的直接矩阵
    '''
    result = np.zeros((dimension, dimension), dtype=float)
    for k in range(scores.shape[0]):
        #第k个专家的打分矩阵
        for i in range(dimension):
            for j in range(dimension):
                #打分对应的三角数
                a = numbers[scores[k][i][j]]
                result[i][j] = ((a[2] - a[0]) + (a[1] - a[0]))/3 + a[0]
    maxR = np.max(np.sum(result, axis=1))
    maxC = np.max(np.sum(result, axis=0))
    return result / max(maxR, maxC)

def cfcs_alg(numbers, scores, dimension):
    '''
        使用CFCS方法进行模糊矩阵清晰化处理
    '''
    #四个维度分别对应minL, minM, minR, maxR
    minMax = np.zeros((4, dimension, dimension), dtype=float)
    for k in range(scores.shape[0]):
        for i in range(dimension):
            for j in range(dimension):
                a = numbers[S[k][i][j]]
                if k == 0:
                    minMax[0][i][j] = a[0]
                    minMax[1][i][j] = a[1]
                    minMax[2][i][j] = a[2]
                    minMax[3][i][j] = a[2]
                else:
                    if a[0] < minMax[0][i][j]:
                        minMax[0][i][j] = a[0]
                    if a[1] < minMax[1][i][j]:
                        minMax[1][i][j] = a[1]
                    if a[2] < minMax[2][i][j]:
                        minMax[2][i][j] = a[2]
                    if a[2] > minMax[3][i][j]:
                        minMax[3][i][j] = a[2]
    result = np.zeros((dimension, dimension), dtype=float)
    for k in range(scores.shape[0]):
        #第k个专家的打分矩阵
        for i in range(dimension):
            for j in range(dimension):
                #打分对应的三角数
                a = numbers[scores[k][i][j]]
                #delta = maxR - minL
                delta = minMax[3][i][j] - minMax[0][i][j]
                xl = (a[0] - minMax[0][i][j])/delta
                #TODO 两篇论文中一个是 (m - minM)/delta， 一个是 (m - minL)/delta, xr也类似
                xm = (a[1] - minMax[1][i][j])/delta
                xr = (a[2] - minMax[2][i][j])/delta
                #计算左标准值（ls）和右标准值（rs）
                ls = xm / (1+xm-xl)
                rs = xr / (1+xr-xm)
                #rs*rs在论文中是rsgrs，其中的g在上下文中没有说明, 其他论文中看到对应位置是一个乘法
                x = (ls * (1-ls) + rs*rs) / (1+ls-rs)
                z = minMax[0][i][j] + x * delta
                result[i][j] += z
    #直接矩阵
    result = result/scores.shape[0]
    resultSum = np.sum(result, axis=1)
    #TODO s的计算是否正确？
    max = 1/np.max(resultSum)
    #归一化直接矩阵
    return max * result

def demetal(N, dimension):
    '''
        决策实验室分析
    '''
    #计算综合影响矩阵: T = N * (I - N)^-1
    I = np.matlib.identity(dimension, dtype = float)
    T = N * np.linalg.inv(I-N)
    #影响度
    D = np.sum(numpy.array(T), axis=1)
    #被影响度
    C = np.sum(numpy.array(T), axis=0)
    #中心度
    M = D + C
    #原因度
    R = D - C
    print(T)
    print(D)
    print(C)
    print(M)
    print(R) 

#三角模糊数
A = np.array([
    [0,    0,    0.25], #无影响N
    [0,    0.25, 0.5], #很弱影响VL
    [0.25, 0.5,  0.75], #弱影响L
    [0.5,  0.75, 1], #强影响H
    [0.75, 1,    1] #很强影响VH
])

#对影响因素间的关系专家打分, 0表示无影响， 1表示很弱影响, 2表示弱影响，3表示强影响，4表很强影响
S = np.array([
 #第一个的打分
 [[1, 2, 3, 4, 0], [3, 4, 0, 3, 1], [2, 3, 2, 3, 3], [1, 2, 3, 4, 0], [1, 2, 3, 4, 0]],
 #第二个的打分
 [[4, 4, 3, 2, 1], [2, 2, 3, 4, 0], [1, 2, 3, 4, 0], [1, 2, 3, 4, 0], [1, 2, 3, 4, 0]]
 #其他打分...
])

#影响因素数量
dimension = S.shape[1]
T = centroid_alg(A, S, dimension)
demetal(T, dimension)
print("=====CFCS")
T = cfcs_alg(A, S, dimension)
demetal(T, dimension)